/**
 * Final Capture Script - Complete Encryption Analysis
 * 完整捕获数美加密流程
 */

console.log("\n" + "=".repeat(80));
console.log("数美SDK - 完整加密流程捕获");
console.log("=".repeat(80) + "\n");

function bytesToHex(bytes) {
    let hex = "";
    for (let i = 0; i < bytes.length; i++) {
        const byte = bytes[i] & 0xFF;
        hex += ("0" + byte.toString(16)).slice(-2);
    }
    return hex;
}

function bytesToString(bytes) {
    let str = "";
    for (let i = 0; i < bytes.length; i++) {
        const c = bytes[i] & 0xFF;
        if (c >= 32 && c <= 126) {
            str += String.fromCharCode(c);
        } else {
            str += ".";
        }
    }
    return str;
}

// ============================================================================
// Part 1: Hook Native Library (libsmsdk.so)
// ============================================================================

setTimeout(function() {
    console.log("[1] 查找libsmsdk.so...");
    const soModule = Process.findModuleByName("libsmsdk.so");
    
    if (!soModule) {
        console.log("    ✗ 未找到libsmsdk.so，稍后重试");
        return;
    }
    
    console.log("    ✓ 找到libsmsdk.so");
    console.log("    Base: " + soModule.base);
    console.log("    Size: " + soModule.size);
    console.log("    Path: " + soModule.path + "\n");
    
    // Hook AES encryption function at offset 0x4AAE4
    console.log("[2] Hook AES加密函数 (sub_4AAE4)...");
    const aesEncAddr = soModule.base.add(0x4AAE4);
    console.log("    Address: " + aesEncAddr);
    
    Interceptor.attach(aesEncAddr, {
        onEnter: function(args) {
            console.log("\n" + "=".repeat(80));
            console.log("🔐 AES加密调用");
            console.log("=".repeat(80));
            
            // args[0] = output buffer
            // args[1] = input buffer
            // args[2] = input length
            // args[3] = key
            // args[4] = key length
            
            const inputPtr = args[1];
            const inputLen = args[2].toInt32();
            const keyPtr = args[3];
            const keyLen = args[4].toInt32();
            
            console.log("输入长度: " + inputLen + " bytes");
            console.log("密钥长度: " + keyLen + " bytes");
            
            // Read input data
            if (inputLen > 0 && inputLen < 10000) {
                try {
                    const input = inputPtr.readByteArray(Math.min(inputLen, 256));
                    console.log("\n输入数据 (前256字节):");
                    console.log("HEX: " + bytesToHex(Array.from(new Uint8Array(input))));
                    console.log("STR: " + bytesToString(Array.from(new Uint8Array(input))));
                } catch(e) {
                    console.log("无法读取输入数据: " + e);
                }
            }
            
            // Read key
            if (keyLen > 0 && keyLen < 1000) {
                try {
                    const key = keyPtr.readByteArray(keyLen);
                    console.log("\n🔑 AES密钥 (" + keyLen + " bytes):");
                    console.log("HEX: " + bytesToHex(Array.from(new Uint8Array(key))));
                    console.log("STR: " + bytesToString(Array.from(new Uint8Array(key))));
                } catch(e) {
                    console.log("无法读取密钥: " + e);
                }
            }
            
            console.log("=".repeat(80) + "\n");
        },
        onLeave: function(retval) {
            console.log("AES加密返回值: " + retval);
        }
    });
    
    console.log("    ✓ 已Hook AES加密\n");
    
    // Hook RSA encryption
    console.log("[3] Hook RSA加密...");
    const rsaEncrypt = Module.findExportByName("libcrypto.so", "RSA_public_encrypt");
    
    if (rsaEncrypt) {
        console.log("    Address: " + rsaEncrypt);
        
        Interceptor.attach(rsaEncrypt, {
            onEnter: function(args) {
                const flen = args[0].toInt32();
                const from = args[1];
                
                console.log("\n" + "=".repeat(80));
                console.log("📦 RSA加密调用");
                console.log("=".repeat(80));
                console.log("明文长度: " + flen + " bytes");
                
                if (flen > 0 && flen < 1000) {
                    try {
                        const plaintext = from.readByteArray(flen);
                        console.log("\nRSA加密前的明文:");
                        console.log("HEX: " + bytesToHex(Array.from(new Uint8Array(plaintext))));
                        console.log("STR: " + bytesToString(Array.from(new Uint8Array(plaintext))));
                        console.log("=".repeat(80) + "\n");
                    } catch(e) {
                        console.log("无法读取明文: " + e);
                    }
                }
            },
            onLeave: function(retval) {
                console.log("RSA加密返回: " + retval + " bytes\n");
            }
        });
        
        console.log("    ✓ 已Hook RSA加密\n");
    } else {
        console.log("    ✗ 未找到RSA_public_encrypt\n");
    }
    
    console.log("=".repeat(80));
    console.log("✓ Native Hook完成，等待加密调用...");
    console.log("=".repeat(80) + "\n");
    
}, 500);

// ============================================================================
// Part 2: Hook Java Crypto (backup)
// ============================================================================

setTimeout(function() {
    try {
        Java.perform(function() {
            console.log("[4] 设置Java层Hook (backup)...\n");
        
        try {
            // Hook Base64
            const Base64 = Java.use("android.util.Base64");
            
            Base64.encodeToString.overload('[B', 'int').implementation = function(input, flags) {
                const result = this.encodeToString(input, flags);
                
                // Only log if result starts with 'B' (our encrypted dev field pattern)
                if (result.length > 60 && result.length < 100 && result.charAt(0) === 'B') {
                    console.log("\n" + "-".repeat(80));
                    console.log("📤 Base64编码 (可能是最终输出)");
                    console.log("-".repeat(80));
                    console.log("输入长度: " + input.length);
                    console.log("输入HEX (前32字节): " + bytesToHex(input.slice(0, Math.min(32, input.length))));
                    console.log("输出长度: " + result.length);
                    console.log("输出: " + result);
                    console.log("-".repeat(80) + "\n");
                }
                
                return result;
            };
            
            console.log("    ✓ 已Hook Base64.encodeToString");
            
        } catch(e) {
            console.log("    ✗ Base64 Hook失败: " + e);
        }
        
            console.log("\n" + "=".repeat(80));
            console.log("✓ 所有Hook就绪！");
            console.log("=".repeat(80) + "\n");
        });
    } catch(e) {
        console.log("[!] Java Hook失败 (这是正常的，我们主要依赖Native Hook): " + e.message);
    }
}, 3000);


